package com.example.subsoilerwifi;

import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.text.DecimalFormat;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView mTvWifiStatus, mTvCurrentAngle, mTvCurrentAngleB, mTvCurrentDepth,
            mTvSensorModel, mTvPloughModel, mTvPloughState;
    private Button mBtnReadParamenter, mBtnWriteParamenter, mBtnWriteAngleAndDepth, mBtnAutoAngle
            ,  mBtnClear, mBtnRestart, mBtnAutoAngleB,
             mBtnScan, mBtnScanTerminalId;
    private EditText mEtIpAddress, mEtPort, mEtTerminalId, mEtNumberPlate, mEtCcid,
            mEtMachineWidth, mEtDepth, mEtRefDepth, mEtAngle, mEtA_SensorHeight, mEtAngleB,
            mEtA_SensorHeightB, mET_CardId;
    private LinearLayout mLlSensorA, mLlSensorB;
    private CheckBox mCbPloughModel;

    int g_sensor_model, g_plough_model, g_plough_state;
    float g_currentAngle, g_currentAngle_b;
    int g_currentDepth;

    private boolean runing = true;
    private final int CONNECTED_MSG = 1001;
    private final int DISCONNECTED_MSG = 1002;
    private final int READ_SUCCESS_MSG = 1003;
    private final int READ_ERR_MSG = 1004;
    private final int WRITE_SUCCESS_MSG = 1005;
    private final int WRITE_ERR_MSG = 1006;
    private final int WRITE_DEPTH_SUCCESS_MSG = 1007;
    private final int WRITE_DEPTH_ERR_MSG = 1008;
    private final int AUTO_ANGLE_SUCCESS_MSG = 1009;
    private final int AUTO_ANGLE_ERR_MSG = 1010;
    private final int DEPTH_ADJUST_SUCCESS_MSG = 1011;
    private final int DEPTH_ADJUST_ERR_MSG = 1012;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case CONNECTED_MSG:
                    mTvWifiStatus.setText("已连接");
                    mTvWifiStatus.setTextColor(Resources.getSystem().getColor(android.R.color.holo_green_light));
                    enableButton(true);
                    DecimalFormat format = new DecimalFormat("0.000000");
                    mTvCurrentAngle.setText(format.format(g_currentAngle / 100.0));
                    mTvCurrentAngleB.setText(format.format(g_currentAngle_b / 100.0));
                    mTvCurrentDepth.setText(g_currentDepth + "");

                    if (g_currentAngle != 0 && g_currentAngle_b == 0) {
                        mLlSensorA.setVisibility(View.VISIBLE);
                        mLlSensorB.setVisibility(View.GONE);
                        mBtnAutoAngle.setVisibility(View.VISIBLE);
                        mBtnAutoAngleB.setVisibility(View.GONE);
                    } else if (g_currentAngle == 0 && g_currentAngle_b != 0) {
                        mLlSensorA.setVisibility(View.GONE);
                        mLlSensorB.setVisibility(View.VISIBLE);
                        mBtnAutoAngle.setVisibility(View.GONE);
                        mBtnAutoAngleB.setVisibility(View.VISIBLE);
                    } else if (g_currentAngle != 0 && g_currentAngle_b != 0) {
                        mLlSensorA.setVisibility(View.VISIBLE);
                        mLlSensorB.setVisibility(View.VISIBLE);
                        mBtnAutoAngle.setVisibility(View.VISIBLE);
                        mBtnAutoAngleB.setVisibility(View.VISIBLE);
                    }

                    if (g_sensor_model == 1) {
                        mTvSensorModel.setTextColor(Resources.getSystem().getColor(android.R.color.holo_green_light));
                        mTvSensorModel.setText("传感器A");
                    } else if (g_sensor_model == 2) {
                        mTvSensorModel.setTextColor(Resources.getSystem().getColor(android.R.color.holo_green_light));
                        mTvSensorModel.setText("传感器B");
                    } else if (g_sensor_model == 3) {
                        mTvSensorModel.setTextColor(Resources.getSystem().getColor(android.R.color.holo_green_light));
                        mTvSensorModel.setText("传感器AB");
                    }else {
                        mTvSensorModel.setTextColor(Resources.getSystem().getColor(android.R.color.holo_red_light));
                        mTvSensorModel.setText("角度传感器异常");
                    }

                    if (g_plough_model == 1) {
                        mTvPloughModel.setTextColor(Resources.getSystem().getColor(android.R.color.holo_green_light));
                        mTvPloughModel.setText("识别器已启用");
                    } else if (g_plough_model == 0) {
                        mTvPloughModel.setTextColor(Resources.getSystem().getColor(android.R.color.holo_red_light));
                        mTvPloughModel.setText("识别器未启用");
                    }

                    if (g_plough_state == 1) {
                        mTvPloughState.setTextColor(Resources.getSystem().getColor(android.R.color.holo_green_light));
                        mTvPloughState.setText("识别器正常");
                    } else if (g_plough_state == 0) {
                        mTvPloughState.setTextColor(Resources.getSystem().getColor(android.R.color.holo_red_light));
                        mTvPloughState.setText("识别器异常");
                    }
                    break;
                case DISCONNECTED_MSG:
                    mTvWifiStatus.setText("未连接");
                    mTvWifiStatus.setTextColor(Resources.getSystem().getColor(android.R.color.holo_red_light));
                    enableButton(false);
                    break;
                case READ_SUCCESS_MSG:
                    Bundle bundle = msg.getData();
                    String data[] = bundle.getStringArray("data");
                    mEtIpAddress.setText(data[0]);
                    mEtPort.setText(data[1]);
                    mEtTerminalId.setText(data[2]);
                    mEtNumberPlate.setText(data[3]);
                    mEtCcid.setText(data[4]);
                    mEtMachineWidth.setText(data[5]);
                    mEtDepth.setText(data[6]);
                    mEtRefDepth.setText(data[7]);
                    mEtAngle.setText(data[8]);
                    mEtA_SensorHeight.setText(data[9]);
                    mEtAngleB.setText(data[11]);
                    mEtA_SensorHeightB.setText(data[12]);
                    int plough_model = Integer.parseInt(data[13]);
                    mET_CardId.setText(data[14]);
                    if (plough_model == 0) {
                        mCbPloughModel.setChecked(false);
                    } else if (plough_model == 1) {
                        mCbPloughModel.setChecked(true);
                    } else {
                        ToastUtils.showToast(MainActivity.this, "犁距传感器读取失败");
                    }
                    ToastUtils.showToast(MainActivity.this, "读取参数成功");
                    break;
                case READ_ERR_MSG:
                    ToastUtils.showToast(MainActivity.this, "读取参数失败");
                    break;
                case WRITE_SUCCESS_MSG:
                    ToastUtils.showToast(MainActivity.this, "设置参数成功");
                    break;
                case WRITE_ERR_MSG:
                    ToastUtils.showToast(MainActivity.this, "设置参数失败");
                    break;
                case WRITE_DEPTH_SUCCESS_MSG:
                    ToastUtils.showToast(MainActivity.this, "设置角度参数成功");
                    break;
                case WRITE_DEPTH_ERR_MSG:
                    ToastUtils.showToast(MainActivity.this, "设置角度参数失败");
                    break;
                case AUTO_ANGLE_SUCCESS_MSG:
                    ToastUtils.showToast(MainActivity.this, "自动设置零点角度成功");
                    break;
                case AUTO_ANGLE_ERR_MSG:
                    ToastUtils.showToast(MainActivity.this, "自动设置零点角度失败");
                    break;
                case DEPTH_ADJUST_SUCCESS_MSG:
                    ToastUtils.showToast(MainActivity.this, "自动校准深度系数成功");
                    break;
                case DEPTH_ADJUST_ERR_MSG:
                    ToastUtils.showToast(MainActivity.this, "自动校准深度系数失败");
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();
        initListeners();
    }

    private void initViews() {
        mTvWifiStatus = findViewById(R.id.tv_wifi_status);
        mTvCurrentAngle = findViewById(R.id.tv_current_angle);
        mTvCurrentAngleB = findViewById(R.id.tv_current_angle_b);
        mTvCurrentDepth = findViewById(R.id.tv_current_depth);
        mTvSensorModel = findViewById(R.id.tv_sensor_model);
        mTvPloughModel = findViewById(R.id.tv_plough_model);
        mTvPloughState = findViewById(R.id.tv_plough_state);

        mBtnReadParamenter = findViewById(R.id.btn_read_parameter);
        mBtnWriteParamenter = findViewById(R.id.btn_write_parameter);
        mBtnWriteAngleAndDepth = findViewById(R.id.btn_write_angleAndDepth);
        mBtnAutoAngle = findViewById(R.id.btn_auto_angle);
        mBtnClear = findViewById(R.id.btn_clear);
        mBtnRestart = findViewById(R.id.btn_restart);
        mBtnScan = findViewById(R.id.btn_scan);
        mBtnScanTerminalId = findViewById(R.id.btn_scan_terminalId);

        mEtIpAddress = findViewById(R.id.et_ip_address);
        mEtPort = findViewById(R.id.et_port);
        mEtTerminalId = findViewById(R.id.et_terminal_id);
        mEtNumberPlate = findViewById(R.id.et_number_plate);
        mEtCcid = findViewById(R.id.et_ccid);
        mEtMachineWidth = findViewById(R.id.et_machine_width);
        mEtDepth = findViewById(R.id.et_depth);
        mEtRefDepth = findViewById(R.id.et_ref_depth);
        mEtAngle = findViewById(R.id.et_angle);
        mLlSensorA = findViewById(R.id.ll_sensor_a);
        mLlSensorB = findViewById(R.id.ll_sensor_b);
        mEtA_SensorHeight = findViewById(R.id.et_a_sensor_height);
        mEtAngleB = findViewById(R.id.et_angle_b);
        mEtA_SensorHeightB = findViewById(R.id.et_a_sensor_height_b);
        mBtnAutoAngleB = findViewById(R.id.btn_auto_angle_b);
        mCbPloughModel = findViewById(R.id.cb_plough_model);
        mET_CardId = findViewById(R.id.et_card_id);
    }

    private void initListeners() {
        mBtnReadParamenter.setOnClickListener(this);
        mBtnWriteParamenter.setOnClickListener(this);
        mBtnWriteAngleAndDepth.setOnClickListener(this);
        mBtnAutoAngle.setOnClickListener(this);
        mBtnClear.setOnClickListener(this);
        mBtnRestart.setOnClickListener(this);
        mBtnAutoAngleB.setOnClickListener(this);
        mBtnScan.setOnClickListener(this);
        mBtnScanTerminalId.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_read_parameter:
                new Thread("read") {
                    @Override
                    public void run() {
                        String reply = SendDataUtils.transact(MainActivity.this, "readParameter");
                        if (reply.startsWith("replyParameter") && reply.endsWith("end")) {
                            String data[] = reply.substring("replyParameter".length() + 1).split(
                                    " ");
                            if (data != null) {
                                Bundle bundle = new Bundle();
                                bundle.putStringArray("data", data);
                                Message msg = mHandler.obtainMessage();
                                msg.setData(bundle);
                                msg.what = READ_SUCCESS_MSG;
                                mHandler.sendMessage(msg);
                            } else {
                                mHandler.sendEmptyMessage(READ_ERR_MSG);
                            }
                        } else {
                            mHandler.sendEmptyMessage(READ_ERR_MSG);
                        }
                    }
                }.start();
                break;
            case R.id.btn_write_parameter:
                int plough_model = 0;
                final String data;
                if (isEmpty(mEtIpAddress) || isEmpty(mEtPort) || isEmpty(mEtTerminalId) || isEmpty(mEtNumberPlate) //|| isEmpty(ccid)
                        || isEmpty(mEtMachineWidth) || isEmpty(mEtDepth) || isEmpty(mEtRefDepth)) {
                    ToastUtils.showToast(MainActivity.this, "请输入完整信息");
                    break;
                }
                String regex = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"; //IP地址正则表达式
                if (!mEtIpAddress.getText().toString().trim().matches(regex)) {
                    ToastUtils.showToast(MainActivity.this, "请输入正确的IP地址");
                    return;
                }
                plough_model = mCbPloughModel.isChecked() ? 1 : 0;
                if (plough_model == 1 && isEmpty(mET_CardId)) {
                    ToastUtils.showToast(MainActivity.this, "请输入犁具识别器ID");
                    return;
                } else if (isEmpty(mET_CardId)) {
                    mET_CardId.setText("0000000001");
                }
                data = "setParameter " + mEtIpAddress.getText().toString().trim() + " " + mEtPort.getText().toString().trim() + " " + mEtTerminalId.getText().toString().trim() + " " + mEtNumberPlate.getText().toString().trim() + " " + mEtMachineWidth.getText().toString().trim() + " " + mEtDepth.getText().toString().trim() + " " + mEtRefDepth.getText().toString().trim() + " " + plough_model + " " + mET_CardId.getText().toString() + " end";
                new Thread("setParameter") {
                    @Override
                    public void run() {
                        String reply = SendDataUtils.transact(MainActivity.this, data);
                        if (reply.equals("okay")) {
                            mHandler.sendEmptyMessage(WRITE_SUCCESS_MSG);
                        } else {
                            mHandler.sendEmptyMessage(WRITE_ERR_MSG);
                        }
                    }
                }.start();
                break;
            case R.id.btn_write_angleAndDepth:
                final String angles;
                int sensorModel = 3;
                if (g_currentAngle != 0 && g_currentAngle_b == 0) {
                    sensorModel = 1;
                } else if (g_currentAngle == 0 && g_currentAngle_b != 0) {
                    sensorModel = 2;
                } else if (g_currentAngle != 0 && g_currentAngle_b != 0) {
                    sensorModel = 3;
                }

                if (sensorModel == 1 && (isEmpty(mEtAngle) || isEmpty(mEtA_SensorHeight))) {
                    ToastUtils.showToast(MainActivity.this, "请输入完整信息");
                    break;
                }
                if (sensorModel == 2 && (isEmpty(mEtAngleB) || isEmpty(mEtA_SensorHeightB))) {
                    ToastUtils.showToast(MainActivity.this, "请输入完整信息");
                    break;
                }
                if (sensorModel == 3 && (isEmpty(mEtAngle) || isEmpty(mEtA_SensorHeight) || isEmpty(mEtAngleB) || isEmpty(mEtA_SensorHeightB))) {
                    ToastUtils.showToast(MainActivity.this, "请输入完整信息");
                    break;
                }

                angles =
                        "setAngleParameter" + " " + mEtAngle.getText().toString().trim() + " " + mEtA_SensorHeight.getText().toString().trim() + " " + sensorModel + " " + mEtAngleB.getText().toString().trim() + " " + mEtA_SensorHeightB.getText().toString().trim() + " end";

                new Thread("setAngleParameter") {
                    @Override
                    public void run() {
                        String reply = SendDataUtils.transact(MainActivity.this, angles);
                        if (reply.equals("okay")) {
                            mHandler.sendEmptyMessage(WRITE_DEPTH_SUCCESS_MSG);
                        } else {
                            mHandler.sendEmptyMessage(WRITE_DEPTH_ERR_MSG);
                        }
                    }
                }.start();
                break;
            case R.id.btn_auto_angle:
                new Thread("autoAngle") {
                    @Override
                    public void run() {
                        String reply = SendDataUtils.transact(MainActivity.this, "autoAngle");
                        if (reply.equals("okay")) {
                            mHandler.sendEmptyMessage(AUTO_ANGLE_SUCCESS_MSG);
                        } else {
                            mHandler.sendEmptyMessage(AUTO_ANGLE_ERR_MSG);
                        }
                    }
                }.start();
                break;
            case R.id.btn_auto_angle_b:
                new Thread("autoAngle") {
                    @Override
                    public void run() {
                        String reply = SendDataUtils.transact(MainActivity.this, "autoAngleB");
                        if (reply.equals("okay")) {
                            mHandler.sendEmptyMessage(AUTO_ANGLE_SUCCESS_MSG);
                        } else {
                            mHandler.sendEmptyMessage(AUTO_ANGLE_ERR_MSG);
                        }
                    }
                }.start();
                break;
            case R.id.btn_clear:
                mEtIpAddress.getText().clear();
                mEtPort.getText().clear();
                mEtTerminalId.getText().clear();
                mEtNumberPlate.getText().clear();
                mEtMachineWidth.getText().clear();
                mEtDepth.getText().clear();
                mEtRefDepth.getText().clear();
                mEtAngle.getText().clear();
                mEtA_SensorHeight.getText().clear();
                mEtAngleB.getText().clear();
                mEtA_SensorHeightB.getText().clear();
                break;
            case R.id.btn_restart:
                new AlertDialog.Builder(this).setTitle("提示").setMessage("是否需要重启设备").setNegativeButton("取消", null).setPositiveButton("重启", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        new Thread("restart") {
                            @Override
                            public void run() {
                                String result = SendDataUtils.transact(MainActivity.this,
                                        "restart 3699");
                            }
                        }.start();
                    }
                }).show();
                break;
            case R.id.btn_scan:
                if (checkPermission()) {
                    Intent intent = new Intent(MainActivity.this, ScanActivity.class);
                    startActivityForResult(intent, 88);
                }
                break;
            case R.id.btn_scan_terminalId:
                if (checkPermission()) {
                    Intent intent = new Intent(MainActivity.this, ScanActivity.class);
                    startActivityForResult(intent, 89);
                }
                break;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        runing = true;
        new Thread("heartbeat") {
            @Override
            public void run() {
                while (runing) {
                    String reply = SendDataUtils.transact(MainActivity.this,
                            "getCurrentAngleAndDepth");
                    String[] values = reply.split(" ");
                    if (reply.startsWith("replayAngleAndDepth") && values.length == 7) {
                        g_currentAngle = Float.parseFloat(values[1]);
                        g_currentDepth = Integer.parseInt(values[2]);
                        g_currentAngle_b = Float.parseFloat(values[3]);
                        g_sensor_model = Integer.parseInt(values[4]);
                        g_plough_model = Integer.parseInt(values[5]);
                        g_plough_state = Integer.parseInt(values[6]);
                        mHandler.sendEmptyMessage(CONNECTED_MSG);
                    } else {
                        mHandler.sendEmptyMessage(DISCONNECTED_MSG);
                    }
                    SystemClock.sleep(1000 * 1);//1 seconds
                }
            }
        }.start();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    private boolean isEmpty(EditText t) {
        return TextUtils.isEmpty(t.getText().toString().trim());
    }

    private void enableButton(boolean enable) {
        mBtnReadParamenter.setEnabled(enable);
        mBtnWriteParamenter.setEnabled(enable);
        mBtnWriteAngleAndDepth.setEnabled(enable);
        mBtnAutoAngle.setEnabled(enable);
        mBtnAutoAngleB.setEnabled(enable);
    }

    public boolean checkPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
            return false;
        } else {
            return true;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 88 && resultCode == RESULT_OK) {
            String card = data.getStringExtra("card");
            mET_CardId.setText(card);
        } else if (requestCode == 89 && resultCode == RESULT_OK) {
            String terminalId = data.getStringExtra("card");
            mEtTerminalId.setText(terminalId);
        }
    }
}
